package com.rdgzs.framework.utilsTools;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * ###################################################
 * 创建日期：2012－12－21
 * 开发人员：李广彬
 * 功能描述：敏感词 工具类
 * 			1.将一个字符串List 转为Map树
 * 			2.对指定的字符串进行敏感词匹配返回匹配的字符串列表
 * 修改日志：
 * ###################################################
 */
public class SensitiveWordUtils {
	public static String LEVEL_1_WORDS_KEY;
	public static String LEVEL_2_WORDS_KEY;
	public static Map excludeKeies=new HashMap();
	public static final Set<String> STOP_WORDS = new HashSet<String>(Arrays.asList(new String[] { " ", "'", "、", "。",
			"·", "ˉ", "ˇ", "々", "—", "～", "‖", "…", "‘", "’", "“", "”", "〔", "〕", "〈", "〉", "《", "》", "「", "」", "『",
			"』", "〖", "〗", "【", "】", "±", "＋", "－", "×", "÷", "∧", "∨", "∑", "∏", "∪", "∩", "∈", "√", "⊥", "⊙", "∫",
			"∮", "≡", "≌", "≈", "∽", "∝", "≠", "≮", "≯", "≤", "≥", "∞", "∶", "∵", "∴", "∷", "♂", "♀", "°", "′", "〃",
			"℃", "＄", "¤", "￠", "￡", "‰", "§", "☆", "★", "〇", "○", "●", "◎", "◇", "◆", "□", "■", "△", "▽", "⊿", "▲",
			"▼", "◣", "◤", "◢", "◥", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▓",
			"※", "→", "←", "↑", "↓", "↖", "↗", "↘", "↙", "〓", "ⅰ", "ⅱ", "ⅲ", "ⅳ", "ⅴ", "ⅵ", "ⅶ", "ⅷ", "ⅸ", "ⅹ", "①",
			"②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "⑩", "⒈", "⒉", "⒊", "⒋", "⒌", "⒍", "⒎", "⒏", "⒐", "⒑", "⒒", "⒓",
			"⒔", "⒕", "⒖", "⒗", "⒘", "⒙", "⒚", "⒛", "⑴", "⑵", "⑶", "⑷", "⑸", "⑹", "⑺", "⑻", "⑼", "⑽", "⑾", "⑿", "⒀",
			"⒁", "⒂", "⒃", "⒄", "⒅", "⒆", "⒇", "Ⅰ", "Ⅱ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅸ", "Ⅹ", "Ⅺ", "Ⅻ", "！", "”",
			"＃", "￥", "％", "＆", "’", "（", "）", "＊", "＋", "，", "－", "．", "／", "０", "１", "２", "３", "４", "５", "６", "７",
			"８", "９", "：", "；", "＜", "＝", "＞", "？", "＠", "〔", "＼", "〕", "＾", "＿", "‘", "｛", "｜", "｝", "∏", "Ρ", "∑",
			"Υ", "Φ", "Χ", "Ψ", "Ω", "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π",
			"ρ", "σ", "τ", "υ", "φ", "χ", "ψ", "ω", "（", "）", "〔", "〕", "＾", "﹊", "﹍", "╭", "╮", "╰", "╯", "", "_",
			"", "^", "（", "^", "：", "！", "/", "\\", "\"", "<", ">", "`", "·", "。", "{", "}", "~", "～", "(", ")", "-",
			"√", "$", "@", "*", "&", "#", "卐", "㎎", "㎏", "㎜", "㎝", "㎞", "㎡", "㏄", "㏎", "㏑", "㏒", "㏕" ,"的"}));


	
	public static void main(String[] args) {
		List<String> words = new ArrayList();
		words.add("呀124423");
		words.add("李广彬");
		words.add("李广勇");
		words.add("李广彬是好人");
		Map treeMap = StrList2MapTree(words);
		
		for(String key:STOP_WORDS){
			char ckey=key.charAt(0);
			excludeKeies.put(ckey, ckey);
		}
		matching("李广 ㎝是好人ldfjlsdjk",treeMap);
		
		//System.out.print("111".substring(8));
	}
	
	/**
	 * 将一个字符串List转为Map树
	 * 
	 * @param dateStr
	 * @return
	 * @
	 * @throws Exception
	 */
	public static Map StrList2MapTree(List<String> words) {
		Map treeMap = new HashMap();
		int maxLen = 0;
		int minLen = 100;
		for (String word : words) {
			word = word.trim();
			if (minLen > word.length()) {
				minLen = word.length();
			}
			if (maxLen < word.length()) {
				maxLen = word.length();
			}
			treeMap = Str2MapTree(treeMap, word);
		}
		treeMap.put("maxLen", maxLen);
		treeMap.put("minLen", minLen);
		System.out.println(treeMap);
		return treeMap;
	}
	
	/**
	 * 将一个字符串转为Map树
	 * 
	 * @param dateStr
	 * @return
	 * @
	 * @throws Exception
	 */
	public static Map Str2MapTree(final Map treeMap, final String words) {
		char[] wordArr = words.toCharArray();
		Map currTreeNode = treeMap;//树的当前位置
		int i = 1;
		for (char word : wordArr) {
			char key = word;
			Map node = (Map) currTreeNode.get(key);
			boolean isNewNode = false;
			if (node == null) {
				node = new HashMap();
				isNewNode = true;
			}
			if (i++ == wordArr.length) {//最后一个时
				node.put("end", true);//敏感词结束标志
				currTreeNode.put(key, node);
			} else {
				if (isNewNode) {
					currTreeNode.put(key, node);//初始化敏感词树的下一个结点	
				}
				currTreeNode = node;
			}
		}
		return treeMap;
	}
	
	/**
	 * 匹配给定的字符串在敏感词中的内容数据
	 * 
	 * @param dateStr
	 * @return
	 * @
	 * @throws Exception
	 */
	public static List matching(final String content, final Map treeMap)  {
		List matStrList = new ArrayList();
		String vldStr = content.trim();
		String ppStr="";
		char[] vldChars = vldStr.toCharArray();
		char word;
		int maxLen = (Integer) treeMap.get("maxLen");
		int minLen = (Integer) treeMap.get("minLen");
		
		for(int i=0;i<vldChars.length;i++){
			word=vldChars[i];
			System.out.print(i);
			if (excludeKey(word, excludeKeies)) {//是否是排除字符
				continue;
			}
			if (isKey(word, treeMap)) {//
				ppStr=matching(content,treeMap,i,maxLen,minLen);
				if(ppStr.length()>0){
					i+=ppStr.length()-1;//-1因为i++ 还会增1
				}
				
			}else{
				continue;
			}
		}
		
		return null;
	}
	
	/**
	 * 每次找到匹配的最长
	 * 
	 * @param dateStr
	 * @return
	 * @throws Exception
	 */
	public static String matching(final String content,final Map treeMap,final int index,final int maxLen,final int minLen)  {
		String matStr = "";
		Map currNode=treeMap;
		int vldStrLen=content.length();
		char word;
		StringBuffer ppStr=new StringBuffer("");
		for(int i=index;i<content.length();i++){
			word=content.charAt(i);
			System.out.println(word);
			//1.从指定的坐标开始向下寻找
			//2.跳过 忽略列表里的 字符
			//3.取得一个匹配列表
			ppStr.append(word);
			if (excludeKey(word, excludeKeies)) {//是否是排除字符
				continue;
			}
			currNode=(Map) currNode.get(word);
			if(currNode!=null){//能找到下级
				Boolean isEnd=(Boolean) currNode.get("end");
				if(isEnd!=null&&isEnd){
					matStr=ppStr.toString();
				}
			}else{
				break;
			}
			
		}
	
		System.out.println(matStr);
		return matStr;
	}
	
	/**
	 * 测试指定字符是否在指定的树中
	 * @param key
	 * @param treeMap
	 * @return
	 * @
	 */
	public static boolean isKey(final char key, final Map treeMap)  {
		return treeMap.get(key) == null ? false : true;
	}
	
	/**
	 * 测试指定字符是否在指定的树中
	 * @param key
	 * @param treeMap
	 * @return
	 * @
	 */
	public static boolean excludeKey(final char key, final Map excludeKeies)  {
		return excludeKeies.get(key) == null ? false : true;
	}
}
